package com.wellview.template.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;


import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.animation.ValueAnimator;
import com.wellview.template.R;

/**
 * Created by heqian on 2016/8/16.
 */
public class DoubleBallProgress extends View {

    private final static String TAG = "DoubleBallProgress";

    //默认小球最小半径
    private final static int DEFAULT_MIN_RADIUS = 5;
    //默认小球最大半径
    private final static int DEFAULT_MAX_RADIUS = 15;
    //默认两个小球运行轨迹距离
    private final static int DEFAULT_DISTANCE = 20;
    //默认第一个小球颜色
    private final static int DEFAULT_ONE_BALL_COLOR = Color.parseColor("#40df73");
    //默认第二个小球颜色
    private final static int DEFAULT_TWO_BALL_COLOR = Color.parseColor("#ffdf3e");
    //默认动画执行时间
    private final static int DEFAULT_ANIMATOR_DURATION = 1000;

    private Paint mPaint;
    private float minRadius = 0;
    private float maxRadius = 0;
    private int oneBallColor = 0;
    private int twoBallColor = 0;
    private int distance = 0;
    private long animatorDuration = 1000;

    private Ball mOneBall;
    private Ball mTwoBall;

    private float mCenterX;
    private float mCenterY;

    private AnimatorSet animatorSet;

    private boolean onMeasureFlag;

    public DoubleBallProgress(Context context) {
        this(context,null );
    }

    public DoubleBallProgress(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DoubleBallProgress(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DoubleBallProgress);
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm); // 或者可以使用 getResources().getDisplayMetrics()
        minRadius = typedArray.getDimensionPixelSize(R.styleable.DoubleBallProgress_min_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_MIN_RADIUS, dm));
        maxRadius = typedArray.getDimensionPixelSize(R.styleable.DoubleBallProgress_max_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_MAX_RADIUS, dm));
        distance = typedArray.getDimensionPixelSize(R.styleable.DoubleBallProgress_distance, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_DISTANCE, dm));
        oneBallColor = typedArray.getColor(R.styleable.DoubleBallProgress_one_ball_color, DEFAULT_ONE_BALL_COLOR);
        twoBallColor = typedArray.getColor(R.styleable.DoubleBallProgress_two_ball_color, DEFAULT_TWO_BALL_COLOR);
        animatorDuration = typedArray.getInteger(R.styleable.DoubleBallProgress_duration, DEFAULT_ANIMATOR_DURATION);

        mOneBall = new Ball();
        mTwoBall = new Ball();
        mOneBall.setColor(oneBallColor);
        mTwoBall.setColor(twoBallColor);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        initAnimator();
    }


    /**
     * 进行一些宽和高的测量
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (!onMeasureFlag) {
            Log.d(TAG, "onMeasure: widthMeasureSpec = " + widthMeasureSpec + ",heightMeasureSpec = " + heightMeasureSpec);
            int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSoecSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSoecSize = MeasureSpec.getSize(heightMeasureSpec);
            if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
                setMeasuredDimension(50,50);
            } else if (widthSpecMode == MeasureSpec.AT_MOST){
                setMeasuredDimension(50,heightSoecSize);
            } else if (heightSpecMode == MeasureSpec.AT_MOST){
                setMeasuredDimension(widthSoecSize,50);
            }
            mCenterX = getWidth() / 2;
            mCenterY = getHeight() / 2;
            onMeasureFlag = true;
        }
    }

    /**
     * 在布局发生变化时的回调函数,间接回去调用onMeasure,onLayout函数重新布局
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Log.d(TAG, "onSizeChanged: w = " + w + ",h = " + h + ",oldw = " + oldw + ",oldh = " + oldh);
        mCenterX = w / 2;
        mCenterY = h / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //画两个小球，半径小的先画，半径大的后画
        if (mOneBall.getRadius() > mTwoBall.getRadius()) {
            mPaint.setColor(mTwoBall.getColor());
            canvas.drawCircle(mTwoBall.getCenterX(), mCenterY, mTwoBall.getRadius(), mPaint);

            mPaint.setColor(mOneBall.getColor());
            canvas.drawCircle(mOneBall.getCenterX(), mCenterY, mOneBall.getRadius(), mPaint);
        } else {
            mPaint.setColor(mOneBall.getColor());
            canvas.drawCircle(mOneBall.getCenterX(), mCenterY, mOneBall.getRadius(), mPaint);

            mPaint.setColor(mTwoBall.getColor());
            canvas.drawCircle(mTwoBall.getCenterX(), mCenterY, mTwoBall.getRadius(), mPaint);
        }
    }

    /**
     * 配置属性动画
     */
    private void initAnimator() {
        Log.d(TAG, "initAnimator was executed");
        float centerRadius = (minRadius + maxRadius) * 0.5f;
        //第一个小球缩放动画，通过改变小球的半径，半径变化规律：中s间大小->最大->中间大小->最小->中间大小
        ObjectAnimator oneScaleAnimator = ObjectAnimator.ofFloat(mOneBall, "radius", centerRadius, maxRadius, centerRadius, minRadius, centerRadius);
        oneScaleAnimator.setRepeatCount(ValueAnimator.INFINITE);
        //第二个小球缩放动画，变化规律：中间大小->最小->中间大小->最大->中间大小
        ObjectAnimator twoScaleAnimator = ObjectAnimator.ofFloat(mTwoBall, "radius", centerRadius, minRadius, centerRadius, maxRadius, centerRadius);
        twoScaleAnimator.setRepeatCount(ValueAnimator.INFINITE);

        //第一个小球位移动画，通过改变小球的圆心的位置，并且进行重绘
        ValueAnimator oneCenterAnimator = ValueAnimator.ofFloat(-1, 0, 1, 0, -1);
        oneCenterAnimator.setRepeatCount(ValueAnimator.INFINITE);
        oneCenterAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (Float) animation.getAnimatedValue();
                float x = mCenterX + (distance) * value;
                mOneBall.setCenterX(x);
                //不停的刷新view，让view不停的重绘
                invalidate();
            }
        });

        //第二个小球位移动画
        ValueAnimator twoCenterAnimator = ValueAnimator.ofFloat(1, 0, -1, 0, 1);
        twoCenterAnimator.setRepeatCount(ValueAnimator.INFINITE);
        twoCenterAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (Float) animation.getAnimatedValue();
                float x = mCenterX + (distance) * value;
                mTwoBall.setCenterX(x);
            }
        });

        animatorSet = new AnimatorSet();
        animatorSet.playTogether(oneScaleAnimator, oneCenterAnimator, twoScaleAnimator, twoCenterAnimator);
        animatorSet.setDuration(animatorDuration);
        // 时间插值器，表示加速度，此处定义的是开始最快，结尾最慢
        animatorSet.setInterpolator(new DecelerateInterpolator());
    }

    /**
     * 加载到window上的时候就开始动画
     */
//    @Override
//    protected void onAttachedToWindow() {
//        super.onAttachedToWindow();
//        startAnimator();
//    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        stopAnimator();
    }

    /**
     * 在该View隐藏的时候关闭动画，在可见的时候开启动画
     *
     * @param v
     */
    @Override
    protected void onVisibilityChanged(View changedView, int v) {
        super.onVisibilityChanged(changedView, v);
        if (v == GONE || v == INVISIBLE) {
            stopAnimator();
        } else {
            startAnimator();
        }
    }

    /**
     * ball
     */
    public class Ball {

        private float radius;//半径
        private float centerX;//圆心
        private int color;//颜色


        public float getRadius() {
            return radius;
        }


        public void setRadius(float radius) {
            this.radius = radius;
        }

        public float getCenterX() {
            return centerX;
        }

        public void setCenterX(float centerX) {
            this.centerX = centerX;
        }

        public int getColor() {
            return color;
        }

        public void setColor(int color) {
            this.color = color;
        }
    }

    /**
     * 设置第一个球的颜色
     *
     * @param color
     */
    public void setOneBallColor(int color) {
        mOneBall.setColor(color);
    }

    /**
     * 设置第二个球的颜色
     *
     * @param color
     */
    public void setmTwoBallColor(int color) {
        mTwoBall.setColor(color);
    }

    /**
     * 设置球的最大半径
     *
     * @param maxRadius
     */
    public void setMaxRadius(float maxRadius) {
        this.maxRadius = maxRadius;
        initAnimator();
    }

    /**
     * 设置球的最小半径
     *
     * @param minRadius
     */
    public void setMinRadius(float minRadius) {
        this.minRadius = minRadius;
        initAnimator();
    }

    /**
     * 设置两个球旋转的最大范围距离
     *
     * @param distance
     */
    public void setDistance(int distance) {
        this.distance = distance;
    }

    public void setDuration(long duration) {
        this.animatorDuration = duration;
        if (animatorSet !=null ) {
            animatorSet.setDuration(duration);
        }
    }

    /**
     * 开始动画
     */
    public void startAnimator() {
        if (getVisibility() != VISIBLE)
            return;
        if (animatorSet.isRunning())
            return;
        if (animatorSet != null) {
            animatorSet.start();
        }
    }

    /**
     * 结束停止动画
     */
    public void stopAnimator() {
        if (animatorSet != null ) {
            animatorSet.end();
        }
    }
}